using System;
using System.Collections.Generic;
using System.Text;
using RapidHDL;

namespace MicroFabric
{
    public class ToplevelHardware : RapidHardware
    {

        //QuickFabric oFabric;  // non XML
        RapidHDL.Fabric.XMLCore oFabric; // XML


        public override bool ConfigureSettings()
        {
            //Settings.OutputPath = "c:\\net\\hdl\\rhdl_out";
            //Settings.InterfaceSourcePath = "c:\\net\\hdl\\picobase";
            //Settings.XilinxToolsPath = "c:\\Xilinx\\10.1\\ISE\\bin\\nt";
            Settings.XilinxToolsPath = "D:\\Xilinx\\11.1\\ISE\\bin\\nt64\\";
            Settings.XilinxChip = "xc4vlx25-sf363-12";
            Settings.OptimizeSpeed = true;
            Settings.TopComponentName = "CFBase";
            Settings.OutputFormat = StructureTransformType.Verilog;
            Settings.SDRAMDataBits = 32;
            Settings.SDRAMAddressBits = 24;
            Settings.SDRAMBankBits = 4;
            Settings.SDRAMMaskBits = 2;
            Settings.SkipVerilogGeneration = false;
            Settings.UseStart = false;
            Settings.BuildHardware = true;
            Settings.ForceBuildHardware = true;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 1;
            Settings.UseSDRAM = true;
            Settings.BuildRemote = true;
            Settings.DisableCheckWellFormed = true;
         
            Settings.UseFIFO = true;

            //Settings.BuildServerPath = "buildserver:8080";
            //Settings.RemoteFPGAServer = "fpgaserver:3406";

            Settings.BuildServerPath = "vlsi:8080";
            Settings.RemoteFPGAServer = "PC:3030";
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            // Interfaces
            TopLevelComponent.SDRAMInterface.Enabled = false;
            TopLevelComponent.FIFOInterface.Enabled = true;
            //TopLevelComponent.TestBusWrite.Join(0);


            // DATA FLOW
            PipelineBuffer oInBuffer = new PipelineBuffer(TopLevelComponent, "in_buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 18, 4);
            oInBuffer.InputBus.Join(TopLevelComponent.FIFOInterface.BusFromExternal);
            PipelineSerialAssembler oAssembler = new PipelineSerialAssembler(TopLevelComponent, "assembler", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 18, 16, 2, 4);
            oAssembler.InputBus.Join(oInBuffer.OutputBus);

            PipelineBuffer oPCFPGABuffer = new PipelineBuffer(TopLevelComponent, "pc_fpga_buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 64, 1);
            oPCFPGABuffer.InputBus.Join(oAssembler.OutputBus);

            PipelineBuffer oFPGAPCBuffer = new PipelineBuffer(TopLevelComponent, "fpga_pc", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 42, 2);

            PipelineBuffer oPCOutBuffer = new PipelineBuffer(TopLevelComponent, "sdram_buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 42, 4);
            oPCOutBuffer.InputBus.Join(oFPGAPCBuffer.OutputBus);

            PipelineSerializer oSerializer = new PipelineSerializer(TopLevelComponent, "serializer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 42, 14);
            oSerializer.InputBus.Join(oPCOutBuffer.OutputBus);
            oSerializer.OutputBus.Join(TopLevelComponent.FIFOInterface.BusFromInternal);
            oSerializer.OffsetAddress = true;

            //oFabric = new QuickFabric(TopLevelComponent, "quick_fabric", TopLevelComponent.MainClock, TopLevelComponent.MainReset);
            oFabric = new RapidHDL.Fabric.XMLCore(TopLevelComponent, "quick_fabric", TopLevelComponent.MainClock, TopLevelComponent.MainReset, "c:\\src\\rapidhdl\\extras\\fabric.xml");

            oFabric.InputBuses["EQI"].Join(oPCFPGABuffer.OutputBus);
            oFabric.OutputBuses["EQO"].Join(oFPGAPCBuffer.InputBus);

            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            oFabric.AddSignalViews();

            return true;
        }

        public void SigalViews(HardwareScript poScript, int piTime)
        {
        }


        public override bool GenerateHardwareScripts()
        {
            HardwareScript oScript = HardwareScripts.NewScript("test");
            oScript.NoReset = true;

            for (int iTime = 0; iTime < 30; iTime++)
            {
                SigalViews(oScript, iTime);
                oFabric.SignalDisplay(oScript, iTime);

            }
            return true;
        }

        public override MicroTraceData GetMicroTraceData()
        {
            return new MicroTraceData(oFabric.GetProgramText(), oFabric.GetProgramAddressToLine(), oFabric.GetBreakpoints(), oFabric.GetOpCodes());
        }

        public override void LoadRAM()
        {
            oFabric.LoadRAMProgram();
        }
    }
}
